home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / MacOS / QuickDraw™ 3D 1.0.6F4 SDK / Samples / SampleCode / Unsupported Libraries / GXtextLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-05  |  12.5 KB  |  432 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:
  2.     text library
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1991 Apple Computer, Inc.  All rights reserved.    */
  5.  
  6.  
  7.     #include <Memory.h>
  8. #ifndef bold
  9.     #include <Quickdraw.h>
  10. #endif
  11. #include "font routines.h"
  12. #include "graphics libraries.h"
  13. #include "layout routines.h"
  14.  
  15.  
  16. gxShape NewChar(const char data, const gxPoint *position)
  17. {
  18.     return GXNewText(1, (const unsigned char *)&data, position);
  19. }
  20.  
  21.  
  22. void SetChar(gxShape target, const char data, const gxPoint *position)
  23. {
  24.     GXSetText(target, 1, (const unsigned char *)&data, position);
  25. }
  26.  
  27.  
  28. void gDrawChar(const char data, const gxPoint *position)
  29. {
  30.     GXDrawText(1, (const unsigned char *)&data, position);
  31. }
  32.  
  33.  
  34. gxShape NewCString(const char *cString, const gxPoint *position)
  35. {
  36.     register long len = 0;
  37.     register const char *find0 = cString;
  38.  
  39.     while (*find0++ != 0)
  40.         ++len;
  41.     return GXNewText(len, (unsigned char *)cString, position);
  42. }
  43.  
  44.  
  45. void SetCString(gxShape source, const char *cString, const gxPoint *position)
  46. {
  47.     register long len = 0;
  48.     register const char *find0 = cString;
  49.  
  50.     while (*find0++ != 0)
  51.         ++len;
  52.     GXSetText(source, len, (unsigned char *)cString, position);
  53. }
  54.  
  55.  
  56. Fixed FixTextWidth(register const unsigned char *ch, register short len)
  57. {
  58.     gxPoint pt;
  59.     gxShape textShape = GXNewText(len, ch, nil);
  60.     Fixed width = GetShapeAdvance(textShape, &pt)->x;
  61.  
  62.     GXDisposeShape(textShape);
  63.     return width;
  64. }
  65.  
  66.  
  67. Fixed FixCStringWidth(register const char *ch)
  68. {
  69.     register long len = 0;
  70.     register const char *find0 = ch;
  71.  
  72.     while (*find0++ != 0)
  73.         ++len;
  74.     return FixTextWidth((unsigned char *) ch, len);
  75. }
  76.  
  77.  
  78. gxShape NewPString(register const char *pString, register const gxPoint *position)
  79. {
  80.     return GXNewText(*pString, (unsigned char *)pString + 1, position);
  81. }
  82.  
  83.  
  84. void SetPString(register gxShape source, register const char *pString, register const gxPoint *position)
  85. {
  86.     GXSetText(source, *pString, (unsigned char *) pString + 1, position);
  87. }
  88.  
  89.  
  90. Fixed FixPStringWidth(register const char *ch)
  91. {
  92.     return FixTextWidth((unsigned char *) ch + 1, *ch);
  93. }
  94.  
  95.  
  96. Fixed FixCharWidth(char ch)
  97. {
  98.     return FixTextWidth((unsigned char *) &ch, 1);
  99. }
  100.  
  101.  
  102. void DrawCString(register const char *ch, register const gxPoint *position)
  103. {
  104.     register long len = 0;
  105.     register const char *find0 = ch;
  106.  
  107.     while (*find0++ != 0)
  108.         ++len;
  109.     GXDrawText(len, (unsigned char *)ch, position);
  110. }
  111.  
  112.  
  113. void DrawPString(register const char *ch, register const gxPoint *position)
  114. {
  115.     GXDrawText(*ch, (unsigned char *)ch + 1, position);
  116. }
  117.  
  118.  
  119. void SetGlyphText(register gxShape source, register unsigned const char *text, long length)
  120. {
  121.     GXSetGlyphs(source, length, text, nil, nil, nil, nil, nil);
  122. }
  123.  
  124.  
  125. void SetGlyphAdvance(register gxShape source, register const long advanceBits[])
  126. {
  127.     GXSetGlyphs(source, 0, nil, nil, advanceBits, nil, nil, nil);
  128. }
  129.  
  130.  
  131. void SetGlyphStyles(register gxShape source, register const short styleRuns[], register const gxStyle glyphStyles[])
  132. {
  133.     GXSetGlyphs(source, 0, nil, nil, nil, nil, styleRuns, glyphStyles);
  134. }
  135.  
  136.  
  137. long GetGlyphText(register gxShape source, register unsigned char *text)
  138. {
  139.     return GXGetGlyphs(source, nil, text, nil, nil, nil, nil, nil, nil);
  140. }
  141.  
  142.  
  143. long GetGlyphAdvance(register gxShape source, register long advanceBits[])
  144. {
  145.     long length;
  146.  
  147.     GXGetGlyphs(source, &length, nil, nil, advanceBits, nil, nil, nil, nil);
  148.     return length;
  149. }
  150.  
  151.  
  152. long GetGlyphStyles(register gxShape source, register short styleRuns[], register gxStyle glyphStyles[])
  153. {
  154.     long runs;
  155.  
  156.     GXGetGlyphs(source, nil, nil, nil, nil, nil, &runs, styleRuns, glyphStyles);
  157.     return runs;
  158. }
  159.  
  160. #define kBoldnessFactor 18
  161.  
  162. static gxTextFace *SetCommonFace(register commonFace face)
  163. {
  164.     register gxTextFace *newFace;
  165.     register long faceLayers = 1;
  166.     register gxFaceLayer *activeLayer;
  167.     gxTransform italicTransform = nil;
  168.     gxStyle nullStyle = nil;
  169.     boolean doOutline = (face & outline) != 0;
  170.     boolean doBold = (face & bold) != 0;
  171.     boolean doShadow = (face & shadow) != 0;
  172.     boolean doShadowOutline = (face & shadow+outline) != 0;
  173.     Fixed standardBolding = fixed1/kBoldnessFactor;
  174.     Fixed shadowBolding = ff(3)/(kBoldnessFactor*2);
  175.     Fixed shadowTranslate = 2*standardBolding / 3;
  176.     
  177.     if (face == 0)
  178.         return nil;
  179.     
  180.     {
  181.         register long shadowOutlineLayers = doShadowOutline ? 2 : 0;
  182.         register long underlineLayers = (face & underline) ? doShadowOutline + 2 : 0;
  183.  
  184.         faceLayers = shadowOutlineLayers + underlineLayers + (shadowOutlineLayers == 0);
  185.     }
  186.     if (face & italic) {
  187.         italicTransform = GXNewTransform();
  188.         
  189.         GXSkewTransform(italicTransform, -fixed1/4, 0, 0, 0);
  190.     }
  191.     if (face & underline) {
  192.         nullStyle = GXNewStyle();
  193.         GXSetStyleTextSize(nullStyle, fixed1);
  194.         GXSetStyleFont(nullStyle, 0);
  195.     }
  196.     
  197.     newFace = (gxTextFace *) NewPtr(sizeof(gxTextFace) +  (faceLayers - gxAnyNumber) * sizeof(gxFaceLayer));
  198.     newFace->faceLayers = faceLayers;
  199.     ResetMapping(&newFace->advanceMapping);
  200.     if ( ((face & extend) != 0) ^ ((face & condense) != 0) )
  201.         if (face & extend)
  202.             ScaleMapping(&newFace->advanceMapping, ff(100)/85, fixed1, 0, 0);
  203.         else
  204.             ScaleMapping(&newFace->advanceMapping, ff(85)/100, fixed1, 0, 0);
  205.     
  206.     activeLayer = &newFace->faceLayer[0];
  207.     
  208.     if (doShadowOutline) {
  209.         if (face & underline) {
  210.             /*** doesn't discriminate between outline and shadow ***/
  211.             activeLayer->outlineFill = gxNoFill;
  212.             activeLayer->flags = gxUnderlineAdvanceLayer;
  213.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  214.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  215.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(2)/kBoldnessFactor);
  216.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  217.             ++activeLayer;
  218.             
  219.             activeLayer->outlineFill = gxNoFill;
  220.             activeLayer->flags = gxUnderlineAdvanceLayer;
  221.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  222.             GXSetStylePen(activeLayer->outlineStyle, fixed1/8);
  223.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  224.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(2+doShadow)/kBoldnessFactor);
  225.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  226.             ++activeLayer;
  227.  
  228.             activeLayer->outlineFill = gxNoFill;
  229.             activeLayer->flags = gxUnderlineAdvanceLayer + gxWhiteLayer;
  230.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  231.             GXSetStylePen(activeLayer->outlineStyle, fixed1/16);
  232.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  233.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(2+doShadow)/kBoldnessFactor);
  234.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  235.             ++activeLayer;
  236.         }
  237.         
  238.         activeLayer->outlineFill = gxWindingFill;
  239.         activeLayer->flags = 0;
  240.         activeLayer->outlineStyle = nil;
  241.         activeLayer->boldOutset.x = (doShadow ? shadowBolding : standardBolding) + standardBolding*doBold;
  242.         activeLayer->boldOutset.y = doShadow ? shadowBolding : standardBolding;
  243.         if (doShadow) {
  244.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  245.             GXMoveTransform(activeLayer->outlineTransform, shadowTranslate, shadowTranslate);
  246.         } else
  247.             activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
  248.         ++activeLayer;
  249.         
  250.         activeLayer->outlineFill = gxWindingFill;
  251.         activeLayer->flags = gxWhiteLayer;
  252.         activeLayer->outlineStyle = nil;
  253.         activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
  254.         activeLayer->boldOutset.x = doBold*standardBolding;
  255.         activeLayer->boldOutset.y = 0;  
  256.     } else {
  257.         if (face & underline) {
  258.             activeLayer->outlineFill = gxNoFill;
  259.             activeLayer->flags = gxUnderlineAdvanceLayer;
  260.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  261.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  262.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(doBold+1)/kBoldnessFactor + shadowTranslate);
  263.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  264.             ++activeLayer;
  265.             
  266.             activeLayer->outlineFill = gxNoFill;
  267.             activeLayer->flags = gxUnderlineAdvanceLayer;
  268.             activeLayer->outlineStyle = GXCopyToStyle(nil, nullStyle);
  269.             GXSetStylePen(activeLayer->outlineStyle, fixed1/12);    
  270.             activeLayer->outlineTransform = italicTransform ? GXCopyToTransform(nil, italicTransform) : GXNewTransform();
  271.             GXMoveTransform(activeLayer->outlineTransform, 0, ff(doBold+1)/kBoldnessFactor + shadowTranslate);
  272.             activeLayer->boldOutset.x = activeLayer->boldOutset.y = 0;
  273.             ++activeLayer;
  274.         } 
  275.     
  276.         activeLayer->outlineFill = gxWindingFill;
  277.         activeLayer->flags = 0;
  278.         activeLayer->outlineStyle = nil;
  279.         activeLayer->outlineTransform = italicTransform ? GXCloneTransform(italicTransform) : nil;
  280.         activeLayer->boldOutset.x = doBold * standardBolding;
  281.         activeLayer->boldOutset.y = doBold * standardBolding;
  282.     }
  283.     if (activeLayer != &newFace->faceLayer[faceLayers-1])
  284.         DebugStr((unsigned char *)"\pMiscalculated size of gxTextFace structure");
  285.     
  286.     if (italicTransform)
  287.         GXDisposeTransform(italicTransform);
  288.     if (nullStyle)
  289.         GXDisposeStyle(nullStyle);
  290.         
  291.     return newFace;
  292. }
  293.  
  294.  
  295. static void DisposeFaceParts(gxTextFace *newFace)
  296. {
  297.     long activeLayer = newFace->faceLayers - 1;
  298.  
  299.     do {
  300.         if (newFace->faceLayer[activeLayer].outlineStyle)
  301.             GXDisposeStyle(newFace->faceLayer[activeLayer].outlineStyle);
  302.         if (newFace->faceLayer[activeLayer].outlineTransform)
  303.             GXDisposeTransform(newFace->faceLayer[activeLayer].outlineTransform);
  304.     } while (--activeLayer >= 0);
  305.     DisposePtr((Ptr) newFace);
  306. }
  307.  
  308.  
  309. void SetStyleCommonFace(gxStyle source, commonFace face)
  310. {
  311.     gxTextFace *newFace = SetCommonFace(face);
  312.  
  313.     GXSetStyleFace(source, newFace);
  314.     if (newFace)
  315.         DisposeFaceParts(newFace);
  316. }
  317.  
  318.  
  319. void SetShapeCommonFace(gxShape source, commonFace face)
  320. {
  321.     gxTextFace *newFace = SetCommonFace(face);
  322.  
  323.     GXSetShapeFace(source, newFace);
  324.     if (newFace)
  325.         DisposeFaceParts(newFace);
  326. }
  327.  
  328.  
  329. commonFace GetStyleCommonFace(gxStyle source)
  330. {
  331.     long layers = GXGetStyleFace(source, nil);
  332.  
  333.     if (layers == -1)
  334.         return 0;
  335.     {   gxTextFace *realFacePtr = (gxTextFace *) NewPtr(sizeof(gxTextFace) +  (layers - 1) * sizeof(gxFaceLayer));
  336.         commonFace face = 0;
  337.         long activeLayer = 0;
  338.         gxStyle curStyle;
  339.         gxTransform curTransform;
  340.  
  341.         GXGetStyleFace(source, realFacePtr);
  342.         if (realFacePtr->faceLayers == 2) {
  343.             face |= shadow;
  344.             activeLayer++;
  345.         }
  346.         if (realFacePtr->faceLayer[activeLayer].outlineFill == gxClosedFrameFill)
  347.             face |= outline;
  348.         if (realFacePtr->faceLayer[activeLayer].flags & gxUnderlineAdvanceLayer)
  349.             face |= underline;
  350.         curStyle = realFacePtr->faceLayer[activeLayer].outlineStyle;
  351.         if (curStyle)
  352.         if (realFacePtr->faceLayer[activeLayer].boldOutset.x | realFacePtr->faceLayer[activeLayer].boldOutset.y)
  353.             face |= bold;
  354.         curTransform = realFacePtr->faceLayer[activeLayer].outlineTransform;
  355.         if (curTransform)
  356.         {   gxMapping map;
  357.  
  358.             GXGetTransformMapping(curTransform, &map);
  359.             if (map.map[0][0] >= IntToFixed(100) / 85)
  360.                 face |= extend;
  361.             if (map.map[0][0] <= IntToFixed(85) / 100)
  362.                 face |= condense;
  363.             if (map.map[1][0])
  364.                 face |= italic;
  365.         }
  366.         {   gxFaceLayer *layer = realFacePtr->faceLayer;
  367.  
  368.             while (layers--) {
  369.                 DisposeStyleAt(&layer->outlineStyle);
  370.                 DisposeTransformAt(&layer->outlineTransform);
  371.                 layer++;
  372.             }
  373.         }
  374.         return face;
  375.     }
  376. }
  377.  
  378.  
  379. commonFace GetShapeCommonFace(gxShape source)
  380. {
  381.     return GetStyleCommonFace(GXGetShapeStyle(source));
  382. }
  383.  
  384. #define offsetField(type, field)        ((long) &((type *) 0)->field)
  385.  
  386. gxPoint *GetShapeAdvance(gxShape source, gxPoint *advancePt)
  387. {
  388.     gxShapeType type = GXGetShapeType(source);
  389.  
  390.     switch (type) {
  391.         case gxEmptyType:
  392.         case gxFullType:
  393.     #ifdef debugging
  394.             GXPostGraphicsError(graphic_type_does_not_contain_points);
  395.     #endif
  396.         break;
  397.         case gxPointType:
  398.         case gxLineType:
  399.         case gxCurveType:
  400.         case gxRectangleType:
  401.         case gxPolygonType:
  402.         case gxPathType:
  403.         case gxPictureType:
  404.             {   gxRectangle bounds;
  405.  
  406.                 GXGetShapeBounds(source, 0, &bounds);
  407.                 advancePt->x = bounds.right - bounds.left;
  408.                 advancePt->y = bounds.bottom - bounds.top;
  409.             }
  410.         break;
  411.         case gxTextType:
  412.         case gxGlyphType:
  413.         case gxLayoutType:
  414.             {   long characters;
  415.                 gxPoint *positions;
  416.  
  417.                 if (type == gxTextType)
  418.                     GXGetText(source, &characters, nil, nil);
  419.                 else if (type == gxGlyphType)
  420.                     GXGetGlyphs(source, &characters, nil, nil, nil, nil, nil, nil, nil);
  421.                 else characters = GXGetLayoutGlyphs(source, nil, nil, nil, nil, nil, nil, nil);
  422.                 positions = (gxPoint *) NewPtr((characters + 1) * sizeof(gxPoint));
  423.                 GXGetGlyphMetrics(source, positions, nil, nil);
  424.                 advancePt->x = positions[characters].x - positions[0].x;
  425.                 advancePt->y = positions[characters].y - positions[0].y;
  426.                 DisposePtr((Ptr) positions);
  427.             }
  428.         break;
  429.     }
  430.     return advancePt;
  431. }
  432.